<?php


namespace app\open\controller\bwc;


use app\open\service\OrderService;
use app\common\controller\Api;
use think\Config;
use think\Cache;
use think\Db;
use app\common\model\Order as OrderModel;
use app\common\model\OrderProof;
use app\common\model\OrderLog;
use app\common\model\UserRoll;
use app\common\model\OrderFail;
use fast\Http;
use app\open\service\OcrService;
use app\open\service\PlayService;

/**
 * 订单类
 * Class Order
 * @package app\api\controller
 */
class OrderAction extends Api
{
// 无需登录的接口,*表示全部
    protected $noNeedLogin = ['*'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['*'];


    /**
     * 提交单号锁定名额
     * @DateTime 2023-04-02T19:28:35+0800
     * @return   [type]                   [description]
     */
    public function submitTakeoutNo()
    {
        $params = $this->request->param();
        if (!isset($params['sign']) || !isset($params['clientId']) || !isset($params['timestamp']) || !isset($params['orderNo']) || !isset($params['takeoutOrderNo'])) $this->error('缺少关键参数');
        // 渠道验证
        $channel = Db::name('channel')->where(['clientId'=>$params['clientId'],'status'=>1])->find();
        if (!$channel) $this->error('关键参数不正确');
        // 签名验证
        // $sign = $params['sign'];
        // unset($params['sign']);
        // $comparesign = PlayService::sign($params,$channel['clientSecret']);
        // if ($comparesign!=$sign) $this->error('签名不正确');
        // // 时间验证
        // if (abs(time()-intval($params['timestamp']/1000))>=2) $this->error('请求已过期');
        $order = OrderModel::where('play_order_no',$params['orderNo'])->find();
        if (!$order) {
            $this->error('订单不存在');
        }
        if ($order['order_status']!=1) {
            $this->error('订单状态有误');
        }
        $play = (new \app\admin\model\Play())->where(['play_no' => $order->play_no])->find();
        if (!$play) {
            $this->error('活动不存在');
        }
        // 是否超过30分钟
        if (time()>$order['expire_time']) {
            $this->error('订单已过期');
        }
        $params['takeoutOrderNo'] = intval($params['takeoutOrderNo']);
        // 同一订单号提交过后不可重复提交
        $snNUm = OrderModel::where([
            'wm_order_sn'=>$params['takeoutOrderNo'],
            'order_status' => ['in',[-3,-5,-6,-7,-8,-9,1,2,3,6]],
            'play_order_no' => ['<>',$params['orderNo']]
        ])->find();
        if (count($snNUm)>0) {
            $this->error('该外卖单号已使用过');
        }
        Db::startTrans();
        try {
            // $order->expire_time = time()+intval(config('proof_expire')); // 6hour
            $order->expire_time = strtotime(date('Ymd',$order['place_time']))+129600; // 明天中午12
            $order->wm_order_sn = $params['takeoutOrderNo'];
            $order->save();
            $OrderProof = OrderProof::where('play_order_no',$params['orderNo'])->order('id DESC')->find();
            if (!$OrderProof || $OrderProof['wm_order_sn']!=$params['takeoutOrderNo']) {
                $OrderProof = new OrderProof();
                $data = [
                    'wm_order_sn' => $params['takeoutOrderNo'],
                    // 'merchant_id' => $play['user_id'],
                    'shop_no' => $order['shop_no'],
                    'user_id' => $order['user_id'],
                    'play_order_no' => $params['orderNo'],
                    'platform_no' => $order['platform_no'],
                    'user_pay' => $order['user_pay'],      // 满多少
                    'back_money' => $order['actual_rebate_amt'] //返多少
                ];
                $OrderProof->allowField(true)->save($data);
            } else {
                $OrderProof->wm_order_sn = $params['takeoutOrderNo'];
                $OrderProof->save();
            }
            // orderlog
            OrderLog::create([
                'play_order_id' => $order['id'],
                'play_order_no' => $params['orderNo'],
                'is_front' => 3,
                'info' => '提交单号',
                'create_by' => 'api',
                'create_by_id' => $channel['id'],
            ]);
            // 给渠道发通知
            if ($order['create_by']=='api') {
                $OrderService = new \app\open\service\OrderService();
                $OrderService->statusChange($order['wm_order_sn'],$order['play_order_no'],$order['order_status'],0,$order['actual_rebate_amt'],$order['is_yunzhan']);
            }
            Db::commit();
            $this->success('单号提交成功，请尽快提交下单凭证');
        } catch (Exception $e) {
            \think\Log::write('提交单号：Exception=>'.$e->getMessage(), 'error');
            Db::rollback();
            $this->error('提交单号失败');
        }   
    }

    /**
     * 订单详情
     * @param OrderService $orderService
     */
    public function orderDetail()
    {
        $params = $this->request->param();
        if (!isset($params['sign']) || !isset($params['clientId']) || !isset($params['timestamp']) || !$params['orderNo']) $this->error('缺少关键参数');
        // 渠道验证
        $channel = Db::name('channel')->where(['clientId'=>$params['clientId'],'status'=>1])->find();
        if (!$channel) $this->error('关键参数不正确');
        // 签名验证
        // $sign = $params['sign'];
        // unset($params['sign']);
        // $comparesign = PlayService::sign($params,$channel['clientSecret']);
        // if ($comparesign!=$sign) $this->error('签名不正确');
        // // 时间验证
        // if (abs(time()-intval($params['timestamp']/1000))>=2) $this->error('请求已过期');
        $orderService = new orderService();
        $order = $orderService->getOrderDetail($params['orderNo']);
        if ($order) $this->success('订单详情', $order);
        $this->error('订单信息获取失败');
    }

    /**
     * 提交证明
     * @param OrderService $orderService
     */
    public function submit()
    {
        $params = $this->request->param();
        if (!isset($params['sign']) || !isset($params['clientId']) || !isset($params['timestamp'])) $this->error('缺少关键参数');
        $post = $this->request->post();
        // if (!isset($post['orderNo']) || !isset($post['orderImg'])) $this->error('缺少关键参数');
        // $params = array_merge($params,$post);
        $play_order_no = $params['orderNo'];
        // 针对用户多次请求接口的处理
        // $requestcache = Cache::store('redis')->get('bdbpostproof'.$play_order_no);
        // if ($requestcache && $requestcache==1) exit;
        // $res = Cache::store('redis')->acquireLock('bdbpostproof'.$play_order_no,1,5);
        // if (!$res) exit;
        // 渠道验证
        $channel = Db::name('channel')->where(['clientId'=>$params['clientId'],'status'=>1])->find();
        if (!$channel) $this->error('关键参数不正确');
        // 签名验证
        // $sign = $params['sign'];
        // unset($params['sign']);
        // $comparesign = PlayService::sign($params,$channel['clientSecret']);
        // if ($comparesign!=$sign) $this->error('签名不正确');
        // // 时间验证
        // if (abs(time()-intval($params['timestamp']/1000))>=2) $this->error('请求已过期');
        $order = OrderModel::where('play_order_no',$play_order_no)->find();
        $proof = OrderProof::where('play_order_no',$order['play_order_no'])->order('id DESC')->find();
        if (!$order) {
            $this->error('订单不存在');
        }
        if ($order['order_status']==3 || $order['order_status']==-5) $this->error('您的订单已提交，请勿重复提交^^');
        if ($order['order_status']!=1 && $order['order_status']!=-3) {
            $this->error('订单状态有误');
        }
        if ($order['order_status']==1) {
            if (!$proof) {
                $this->error('未提交订单号');
            }
            if (time()>$order['expire_time']) {
                $this->error('上传凭据超时');
            }
        }
        $proof['upload_time'] = time();
        Db::startTrans();
        try {
            // 被驳回后第二次提交
            if ($order['order_status']==-3 && $proof['machine_audit_state']!=3) {
                if ($proof['handle_status']!=-1 && $proof['handle_status']!=0) {
                // if ($proof['handle_status']!=-1) {
                    $this->error('不能重复提交');
                }
                // 同一订单号提交过后不可重复提交
                $snNUm = OrderModel::where([
                    'wm_order_sn'=>$proof['wm_order_sn'],
                    'order_status' => ['in',[1,2,3,-5,-6,-7,-8,-9]]
                ])->find();
                if (count($snNUm)>0) {
                    $this->error('该外卖单号已使用过');
                }
                // 新的凭据
                $OrderProof = new OrderProof();
                $data = [
                    'wm_order_sn' => $proof['wm_order_sn'],
                    'merchant_id' => $proof['merchant_id'],
                    'shop_no' => $proof['shop_no'],
                    'user_id' => $proof['user_id'],
                    'play_order_no' => $proof['play_order_no'],
                    'platform_no' => $proof['platform_no'],
                    'user_pay' => $proof['user_pay'],
                    'back_money' => $proof['back_money'],
                    'upload_time' => time(),
                    // 'machine_audit_state' => -1
                ];
                $OrderProof->allowField(true)->save($data);
                $proof = OrderProof::where('id',$OrderProof['id'])->order('id DESC')->find();
            } 
            $data = [
                'one_image' => $params['orderImg'],
                'two_image' => '',
            ];
            $play = (new \app\admin\model\Play())->where(['play_no' => $order->play_no])->find();
            if (!$play) {
                $this->error('未找到对应活动');
            }
            if ($play['scheme_no'] !=3) {
                if (!isset($params['feedbackImg']) || !$params['feedbackImg']) $this->error('请上传用餐体验截图');
                $data['three_image'] = $params['feedbackImg'];
            }
            $data['upload_time'] = time();
            $data['handle_status'] = 0;
            $proof->isUpdate(true)->save($data);
            $info = '渠道提交凭据';
            $order->order_status = 2;
            $order->save();
            // orderlog
            \app\common\model\OrderLog::create([
                'play_order_id' => $order['id'],
                'play_order_no' => $order['play_order_no'],
                'create_by' => 'api',
                'create_by_id' => $channel['id'],
                'is_front' => 3,
                'info' => $info,
            ]);
            // 给渠道发通知
            if ($order['create_by']=='api') {
                $OrderService = new \app\open\service\OrderService();
                $OrderService->statusChange($order['wm_order_sn'],$order['play_order_no'],$order['order_status'],0,$order['actual_rebate_amt'],$order['is_yunzhan']);
            }
            Db::commit();
            (new \think\cache\driver\Redis())->lPush('qdorder',$order['play_order_no']);
        } catch (Exception $exception) {
            Db::rollback();
            $this->error($exception->getMessage());
        }
        $this->success('提交成功，等待审核');
    }

    public function cancel()
    {
        $params = $this->request->param();
        if (!isset($params['sign']) || !isset($params['clientId']) || !isset($params['timestamp']) || !isset($params['orderNo'])) $this->error('缺少关键参数');
        $play_order_no = $params['orderNo'];
        // 渠道验证
        $channel = Db::name('channel')->where(['clientId'=>$params['clientId'],'status'=>1])->find();
        if (!$channel) $this->error('关键参数不正确');
        // 签名验证
        // $sign = $params['sign'];
        // unset($params['sign']);
        // $comparesign = PlayService::sign($params,$channel['clientSecret']);
        // if ($comparesign!=$sign) $this->error('签名不正确');
        // // 时间验证
        // if (abs(time()-intval($params['timestamp']/1000))>=2) $this->error('请求已过期');
        $order = (new \app\common\model\Order())->where([
            'play_order_no' => $play_order_no,
        ])->find();
        if (empty($order)) $this->error('不可取消');
        if (in_array($order['order_status'], [1,2,-3,-5,6])) {
            $OrderService = new OrderService();
            $res = $OrderService->cancel($order);
            if ($res) {
                // 给渠道发通知
                if ($order['create_by']=='api') {
                    $OrderService->statusChange($order['wm_order_sn'],$order['play_order_no'],$order['order_status'],0,$order['actual_rebate_amt'],$order['is_yunzhan']);
                }
                $this->success('取消成功');
            }
        }
        $this->error('取消失败');
    }

    /**
     * 预审核
     * @param  string $value [description]
     * @return [type]        [description]
     */
    public function preAudit()
    {
        $params = $this->request->param();
        if (!isset($params['sign']) || !isset($params['clientId']) || !isset($params['timestamp']) || !isset($params['orderNo'])) $this->error('缺少关键参数');
        $play_order_no = $params['orderNo'];
        // 渠道验证
        $channel = Db::name('channel')->where(['clientId'=>$params['clientId'],'status'=>1])->find();
        if (!$channel) $this->error('关键参数不正确');
        // 签名验证
        // $sign = $params['sign'];
        // unset($params['sign']);
        // $comparesign = PlayService::sign($params,$channel['clientSecret']);
        // if ($comparesign!=$sign) $this->error('签名不正确');
        // // 时间验证
        // if (abs(time()-intval($params['timestamp']/1000))>=2) $this->error('请求已过期');
        $order = (new \app\common\model\Order())->where([
            'play_order_no' => $play_order_no,
        ])->find();
        $order->pre_audit = 1;
        $order->save();
        $this->success('success');
    }

    /**
     * 机审订单
     * @return [type] [description]
     */
    public function completeOrder()
    {
        $params = $this->request->post();
        if (!isset($params['orderNo']) || !$params['orderNo']) $this->error('缺少参数');
        $play_order_no = $params['orderNo'];
        $order = OrderModel::where('play_order_no',$play_order_no)->find();
        $proof = OrderProof::where('play_order_no',$order['play_order_no'])->order('id DESC')->find();
        if (!$order || !$proof) {
            $this->error('订单不存在');
        }
        if ($order['order_status']!=2) {
            $this->error('订单状态有误');
        }
        $channel = Db::name('channel')->where('id',$order['is_yunzhan'])->find();
        if (!$channel) $this->error('渠道信息有误');
        Db::startTrans();
        try {
            $play = (new \app\admin\model\Play())->where(['play_no' => $order->play_no])->find();
            if (!$play) {
                $this->error('未找到对应活动');
            }
            $shop = Db::name('shop')->where(['shop_no'=>$order['shop_no']])->field('is_sjzp,middleman_id,shop_no,shop_type,city')->find();
            // 机审接口
            $data['machine_audit_state'] = -1;
            $data['one_image'] = $proof['one_image'];
            $data['two_image'] = $proof['two_image'];
            $data['three_image'] = $proof['three_image'];
            // 当活动为自动审核通过且不是不满意反馈且用户不限制且返现金额小于35
            if ($play['machine_audit']==1) {
                $OcrService = new OcrService();
                $res = $OcrService->ocr1($play, $order, $proof ,$data);
                // $res=['res'=>1,'resarr'=>["订单状态"=>1,"店铺名称"=>1,"订单号"=>1,"下单时间"=>1,"实付金额"=>1,"反馈识别"=>1],'money'=>0,'img_shop_name'=>'','wm_order_sn'=>'','place_time'=>'2025-3-15 12:55:55'];
                if (isset($res['money'])&&$res['money'])$data['actual_pay'] = $res['money'];
                // 调用cps接口查询渠道cps信息
                $cpsstatus = 0;
                if ($channel['cpsQueryUrl']) {
                    $platform_no = 'mt';
                    if ($order['platform_no']==2) $platform_no = 'ele';
                    if ($order['platform_no']==3) $platform_no = 'jd';
                    $cpsparams = ['takeoutOrderNo'=>$order['wm_order_sn'],'source'=>$platform_no];
                    // $cpsres = '{"payAmount": 10,"takeoutOrderNo": "2701848553767702386","payTime": "2025-11-05 12:12:12","orderStatus": 2}';
                    $cpsres = Http::get($channel['cpsQueryUrl'],$cpsparams,[]);
                    \think\Log::write($play_order_no.'cps接口返回：'.$cpsres);
                    if ($cpsres) {
                        $decode = json_decode($cpsres,1);
                        if (isset($decode['payAmount'])) {
                            if ($decode['payAmount']>=$order['user_pay']) {
                                $res['resarr']['实付金额']=1;
                            } else {
                                $res['resarr']['实付金额']=0;
                            }
                        }
                        if (isset($decode['payTime'])) {
                            if (strtotime($decode['payTime'])>=$order['place_time']) {
                                $res['resarr']['下单时间']=1;
                            } else {
                                $res['resarr']['下单时间']=0;
                            }
                        }
                        if (isset($decode['orderStatus'])) {
                            if ($decode['orderStatus']==2) {
                                $res['resarr']['订单状态']=1;
                                $res['resarr']['订单号']=1;
                                $cpsstatus = 1;
                                // 生成cps图片
                                // $orderService = new OrderService();
                                // $data['two_image'] = $orderService->proofImg($play['shop_name'],$order['wm_order_sn'],$decode['payTime'],$decode['payAmount'],$play['shop_type']);
                                // $res['place_time'] = $decode['payTime'];
                                // $res['img_shop_name'] = $play['shop_name'];
                                $res['money'] = $data['actual_pay'] = $decode['payAmount'];
                                if ($order['user_pay']-$data['actual_pay']>0) {
                                    $actual_rebate_amt = $order['rebate_amt']-$order['service_charge_amt']-($order['user_pay']-$data['actual_pay']);
                                    $actual_rebate_amt = $actual_rebate_amt<0?0:round($actual_rebate_amt,2);
                                    $order->actual_rebate_amt = $actual_rebate_amt;
                                    $data['handle_admin_desc'] = 'admin（实付金额不满'.$order['user_pay'].'元，扣除不足金额'.round($order['rebate_amt']-$order['service_charge_amt']-$actual_rebate_amt,2).'）admin';
                                    $data['handle_time'] = time();
                                }
                            } else {
                                $res['resarr']['订单状态']=0;
                            }
                        }
                        $resarr = $res['resarr'];
                        sort($resarr);
                        if ($resarr[0]==1) {
                            $res['res'] = 1;
                        } else {
                            $res['res'] = 0;
                        }
                    }
                }
                $data['machine_audit_desc'] = json_encode($res['resarr'],JSON_UNESCAPED_UNICODE);
                if ($res['res']==1) {
                    $data['machine_audit_state'] = 1;
                }
            }
            // 如果有图片的话不要覆盖空数据
            if (!isset($data['one_image'])) {
                $data['one_image'] = $proof['one_image'];
            }
            if (!isset($data['two_image'])) {
                $data['two_image'] = $proof['two_image'];
            }
            // 机审通过，则订单已完成
            if ($data['machine_audit_state']==1) {
                // 如果订单满足复审条件的同时是立即配送的就不需要复审
                $ljps = 0;
                if ($proof['machine_audit_desc']) {
                    if (strpos($proof['machine_audit_desc'],'立即配送')) $ljps = 1;
                } else {
                    if (isset($res['resarr']['立即配送'])) $ljps = 1;
                }
                if (isset($play['is_sjzp'])) $shop['is_sjzp'] = $play['is_sjzp'];
                $fushen_tips = is_fushen($shop['is_sjzp'],0,$play['back_money'],$play['is_pay'],0,$ljps,$order['create_dt'],$play['play_label'],$order['cps_id'],$play['shop_type']);
                // 商家复审的情况
                if ($fushen_tips) {
                    // $data['handle_admin_id'] = $this->auth->id;
                    $data['handle_status'] = 1;
                    $data['handle_time'] = time();
                    $data['upload_time'] = time();
                    $data['handle_admin_desc'] = 'Admin（'.$fushen_tips.'）商家复审';
                    $proof->isUpdate(true)->save($data);
                    OrderLog::create([
                        'play_order_id' => $order->id,
                        'play_order_no' => $order->play_order_no,
                        'info' => '机审通过，待商家复审',
                        'create_by' => 'api',
                        'create_by_id' => $channel['id'],
                        'is_front' => 3,
                    ]);
                    // 订单状态
                    $order->is_fushen = 1;
                    $order->order_status = 6;
                    // $order->update_by = $this->auth->id;
                    $order->save();
                    // $complete_order = (new OrderModel())->where(['play_no'=>$order['play_no'],'order_status'=>['in',[3,6,-9]]])->count();
                    // // 状态改为待支付
                    // if (($complete_order==$play['chbcquota'] && $play['play_status']==2) || ($play['play_status']==4 && $complete_order==$play['chbcquota']-$play['chbcconsume'] && $play['chbcquota']-$play['chbcconsume']>0)) {
                    //     $play->play_status = 3;
                    //     $play->acture_total_money = (float)(new OrderModel())->where(['play_no'=>$play['play_no'],'order_status'=>['in',[3,6,-9]]])->value('sum(actual_rebate_amt+service_charge_amt)');
                    //     $play->save();
                    // }
                } else {
                    // 订单状态
                    $order->order_status = 3;
                    $order->save();
                    //
                    $data['handle_status'] = 1;
                    $data['handle_time'] = time();
                    $data['upload_time'] = time();
                    $proof->isUpdate(true)->save($data);
                    OrderLog::create([
                        'play_order_id' => $order->id,
                        'play_order_no' => $order->play_order_no,
                        'info' => '机审通过',
                        'create_by' => 'api',
                        'create_by_id' => $channel['id'],
                        'is_front' => 3,
                    ]);
                    // $complete_order = (new OrderModel())->where(['play_no'=>$order['play_no'],'order_status'=>['in',[3,6,-9]]])->count();
                    // // 状态改为待支付
                    // if (($complete_order==$play['chbcquota'] && $play['play_status']==2) || ($play['play_status']==4 && $complete_order==$play['chbcquota']-$play['chbcconsume'] && $play['chbcquota']-$play['chbcconsume']>0)) {
                    //     $play->play_status = 3;
                    //     $play->acture_total_money = (float)(new OrderModel())->where(['play_no'=>$play['play_no'],'order_status'=>['in',[3,6,-9]]])->value('sum(actual_rebate_amt+service_charge_amt)');
                    //     $play->save();
                    // }
                    // 中间人佣金
                    if ($play['is_pay']==1) {
                        $middleman = Db::name('middleman')->where(['id'=>$shop['middleman_id']])->field('rebate_amt,user_id')->find();
                        if (isset($middleman['rebate_amt']) && $middleman['rebate_amt']) {
                            (new \app\common\model\User())->money($middleman['rebate_amt'], $middleman['user_id'], '经纪人收益', $order['play_order_no']);
                        }
                    }
                    OrderLog::create([
                        'play_order_id' => $order->id,
                        'play_order_no' => $order->play_order_no,
                        'info' => '订单完成',
                        'create_by' => 'api',
                        'create_by_id' => $channel['id'],
                        'is_front' => 3,
                    ]);
                    // 给渠道发通知
                    if ($order['create_by']=='api') {
                        $OrderService = new \app\open\service\OrderService();
                        $OrderService->statusChange($order['wm_order_sn'],$order['play_order_no'],$order['order_status'],0,$order['actual_rebate_amt'],$order['is_yunzhan']);
                    }
                }
                
            } else {
                $data['upload_time'] = time();
                $data['handle_status'] = 0;
                $proof->isUpdate(true)->save($data);
                $info = '机审不通过';
                // orderlog
                \app\common\model\OrderLog::create([
                    'play_order_id' => $order['id'],
                    'play_order_no' => $order['play_order_no'],
                    'create_by' => 'api',
                    'create_by_id' => $channel['id'],
                    'is_front' => 3,
                    'info' => $info,
                ]);
            }
            Db::commit();
        } catch (Exception $exception) {
            Db::rollback();
            \think\Log::write('提交活动凭据exception=>'.$exception->getMessage());
            $this->error($exception->getMessage());
        }
        $this->success('success');
    }

    /**
     * 操作成功返回的数据
     * @param string $msg    提示信息
     * @param mixed  $data   要返回的数据
     * @param int    $code   错误码，默认为1
     * @param string $type   输出类型
     * @param array  $header 发送的 Header 信息
     */
    protected function success($msg = '', $data = null, $code = 200, $type = null, array $header = [])
    {
        $this->result($msg, $data, $code, $type, $header);
    }
}